<?php

declare(strict_types=1);

namespace app\service\cart;

use app\model\Cart;
use app\model\Prod;
use app\model\User;
use InvalidArgumentException;
use think\Paginator;

class CartService
{
    public function paginate(int $buyerId, array $filters = [], int $page = 1, int $pageSize = 20): Paginator
    {
        $query = Cart::where('buyer_id', $buyerId)
            ->order(['id' => 'desc']);

        if (isset($filters['status']) && $filters['status'] !== '') {
            $query->where('status', (int) $filters['status']);
        }

        if (!empty($filters['seller_org_id'])) {
            $query->where('seller_org_id', (int) $filters['seller_org_id']);
        }

        return $query->paginate([
            'list_rows' => $pageSize,
            'page' => $page,
        ]);
    }

    public function findById(int $id, int $buyerId): ?Cart
    {
        return Cart::where('id', $id)
            ->where('buyer_id', $buyerId)
            ->find();
    }

    public function add(array $payload): Cart
    {
        $buyerId = (int) ($payload['buyer_id'] ?? 0);
        if ($buyerId <= 0) {
            throw new InvalidArgumentException('buyer_id 参数不合法');
        }

        $productId = (int) ($payload['product_id'] ?? ($payload['prod_id'] ?? 0));
        if ($productId <= 0) {
            throw new InvalidArgumentException('product_id 参数不合法');
        }

        $qty = max(1, (int) ($payload['qty'] ?? 1));
        $skuId = isset($payload['sku_id']) ? (int) $payload['sku_id'] : null;

        /** @var Prod|null $product */
        $product = Prod::find($productId);
        if (!$product) {
            throw new InvalidArgumentException('商品不存在');
        }

        $buyerOrgId = $this->resolveBuyerOrg($buyerId);

        $existing = Cart::where('buyer_id', $buyerId)
            ->where('product_id', $productId)
            ->where('sku_id', $skuId)
            ->find();

        $snapshot = [
            'title' => $product->title,
            'model' => $product->model,
            'cover_image' => $product->cover_image,
            'unit' => $product->unit,
        ];

        if ($existing) {
            $existing->qty = $existing->qty + $qty;
            $existing->snapshot_price = $product->default_price;
            $existing->snapshot_currency = 'CNY';
            $existing->snapshot_attrs = $snapshot;
            $existing->status = 1;
            $existing->remark = (string) ($payload['remark'] ?? $existing->remark);
            $existing->save();

            return $existing;
        }

        /** @var Cart $cart */
        $cart = Cart::create([
            'buyer_id' => $buyerId,
            'buyer_org_id' => $buyerOrgId,
            'seller_org_id' => $product->seller_org_id,
            'product_id' => $productId,
            'sku_id' => $skuId,
            'qty' => $qty,
            'snapshot_price' => $product->default_price,
            'snapshot_currency' => 'CNY',
            'snapshot_attrs' => $snapshot,
            'source_type' => (string) ($payload['source_type'] ?? 'buyer'),
            'channel' => (string) ($payload['channel'] ?? 'web'),
            'status' => 1,
            'remark' => (string) ($payload['remark'] ?? ''),
        ]);

        return $cart;
    }

    public function update(int $cartId, int $buyerId, array $payload): Cart
    {
        $cart = $this->findById($cartId, $buyerId);
        if (!$cart) {
            throw new InvalidArgumentException('购物车记录不存在');
        }

        if (isset($payload['qty'])) {
            $qty = (int) $payload['qty'];
            if ($qty <= 0) {
                throw new InvalidArgumentException('数量必须大于0');
            }
            $cart->qty = $qty;
        }

        if (isset($payload['remark'])) {
            $cart->remark = (string) $payload['remark'];
        }

        if (isset($payload['status'])) {
            $cart->status = (int) $payload['status'];
        }

        $cart->save();

        return $cart;
    }

    public function remove(int $cartId, int $buyerId): bool
    {
        $cart = $this->findById($cartId, $buyerId);
        if (!$cart) {
            throw new InvalidArgumentException('购物车记录不存在');
        }

        return (bool) $cart->delete();
    }

    public function format(Cart $cart): array
    {
        $snapshot = $cart->snapshot_attrs ?? [];

        return [
            'id' => (int) $cart->id,
            'buyer_id' => (int) $cart->buyer_id,
            'buyer_org_id' => $cart->buyer_org_id ? (int) $cart->buyer_org_id : null,
            'seller_org_id' => $cart->seller_org_id ? (int) $cart->seller_org_id : null,
            'product_id' => (int) $cart->product_id,
            'sku_id' => $cart->sku_id ? (int) $cart->sku_id : null,
            'qty' => (int) $cart->qty,
            'snapshot_price' => (float) $cart->snapshot_price,
            'snapshot_currency' => $cart->snapshot_currency,
            'snapshot_attrs' => [
                'title' => $snapshot['title'] ?? '',
                'model' => $snapshot['model'] ?? '',
                'cover_image' => $snapshot['cover_image'] ?? '',
                'unit' => $snapshot['unit'] ?? '',
            ],
            'source_type' => $cart->source_type,
            'channel' => $cart->channel,
            'status' => (int) $cart->status,
            'remark' => $cart->remark,
            'create_time' => $cart->create_time,
            'update_time' => $cart->update_time,
        ];
    }

    public function formatCollection(iterable $carts): array
    {
        $results = [];
        foreach ($carts as $cart) {
            if ($cart instanceof Cart) {
                $results[] = $this->format($cart);
            }
        }

        return $results;
    }

    private function resolveBuyerOrg(int $buyerId): ?int
    {
        /** @var User|null $buyer */
        $buyer = User::find($buyerId);
        if (!$buyer) {
            return null;
        }

        $member = $buyer->orgMembers()->with('org')->find();
        if (!$member || !$member->org) {
            return null;
        }

        return (int) $member->org->id;
    }
}
